Frigør potentialet i GraphQL Federation med Schema Stitching. Lær at bygge en samlet GraphQL API fra flere services, hvilket forbedrer skalerbarhed og vedligeholdelse.
GraphQL Federation: Schema Stitching - En Omfattende Guide
I det konstant udviklende landskab af moderne applikationsudvikling er behovet for skalerbare og vedligeholdelsesvenlige arkitekturer blevet altafgørende. Microservices, med deres iboende modularitet og uafhængige deployerbarhed, er blevet en populær løsning. Men at administrere talrige microservices kan introducere kompleksitet, især når det kommer til at eksponere en samlet API til klientapplikationer. Det er her, GraphQL Federation, og specifikt Schema Stitching, kommer ind i billedet.
Hvad er GraphQL Federation?
GraphQL Federation er en kraftfuld arkitektur, der giver dig mulighed for at bygge en enkelt, samlet GraphQL API fra flere underliggende GraphQL-tjenester (ofte repræsenterende microservices). Det gør det muligt for udviklere at forespørge data på tværs af forskellige tjenester, som om det var en enkelt graf, hvilket forenkler klientoplevelsen og reducerer behovet for kompleks orkestreringslogik på klientsiden.
Der er to primære tilgange til GraphQL Federation:
- Schema Stitching: Dette indebærer at kombinere flere GraphQL-skemaer til et enkelt, samlet skema på gateway-laget. Det er en tidligere tilgang og er afhængig af biblioteker til at håndtere skemakombinationen og forespørgselsdelegering.
- Apollo Federation: Dette er en nyere og mere robust tilgang, der bruger et deklarativt skemasprog og en dedikeret query planner til at styre federationsprocessen. Den tilbyder avancerede funktioner som typeudvidelser, nøgledirektiver og distribueret sporing.
Denne artikel fokuserer på Schema Stitching og udforsker dens koncepter, fordele, begrænsninger og praktiske implementering.
Forståelse af Schema Stitching
Schema Stitching er processen med at flette flere GraphQL-skemaer sammen til et enkelt, sammenhængende skema. Dette samlede skema fungerer som en facade, der skjuler kompleksiteten af de underliggende tjenester for klienten. Når en klient sender en anmodning til det sammensyede skema, dirigerer gatewayen intelligent anmodningen til den eller de relevante underliggende tjenester, henter dataene og kombinerer resultaterne, før de returneres til klienten.
Tænk på det sådan her: Du har flere restauranter (tjenester), der hver især specialiserer sig i forskellige køkkener. Schema Stitching er som en universel menu, der kombinerer alle retterne fra hver restaurant. Når en kunde (klient) bestiller fra den universelle menu, bliver ordren intelligent dirigeret til de relevante restaurantkøkkener, maden tilberedes og kombineres derefter til en enkelt levering til kunden.
Nøglekoncepter i Schema Stitching
- Fjernskemaer (Remote Schemas): Disse er de individuelle GraphQL-skemaer for hver underliggende tjeneste. Hver tjeneste eksponerer sit eget skema, som definerer de data og operationer, den leverer.
- Gateway: Gatewayen er den centrale komponent, der er ansvarlig for at sy fjernskemaerne sammen og eksponere det samlede skema for klienten. Den modtager klientanmodninger, dirigerer dem til de relevante tjenester og kombinerer resultaterne.
- Skemafletning (Schema Merging): Dette er processen med at kombinere fjernskemaerne til et enkelt skema. Dette indebærer ofte at omdøbe typer og felter for at undgå konflikter og at definere relationer mellem typer på tværs af forskellige skemaer.
- Forespørgselsdelegering (Query Delegation): Når en klient sender en anmodning til det sammensyede skema, skal gatewayen delegere anmodningen til den eller de relevante underliggende tjenester for at hente dataene. Dette indebærer at oversætte klientens forespørgsel til en forespørgsel, der kan forstås af fjerntjenesten.
- Resultataggregering (Result Aggregation): Efter at gatewayen har hentet data fra de underliggende tjenester, skal den kombinere resultaterne til et enkelt svar, der kan returneres til klienten. Dette indebærer ofte at transformere dataene, så de passer til strukturen i det sammensyede skema.
Fordele ved Schema Stitching
Schema Stitching tilbyder flere overbevisende fordele for organisationer, der anvender en microservices-arkitektur:
- Samlet API: Giver en enkelt, konsistent API for klienter, hvilket forenkler dataadgang og reducerer behovet for, at klienter interagerer direkte med flere tjenester. Dette resulterer i en renere og mere intuitiv udvikleroplevelse.
- Reduceret klientkompleksitet: Klienter behøver kun at interagere med det samlede skema, hvilket skærmer dem for kompleksiteten i den underliggende microservices-arkitektur. Dette forenkler udviklingen på klientsiden og reducerer mængden af kode, der kræves på klienten.
- Øget skalerbarhed: Giver dig mulighed for at skalere individuelle tjenester uafhængigt baseret på deres specifikke behov. Dette forbedrer systemets samlede skalerbarhed og modstandsdygtighed. For eksempel kan en brugertjeneste, der oplever høj belastning, skaleres uden at påvirke andre tjenester som produktkataloget.
- Forbedret vedligeholdelsesvenlighed: Fremmer modularitet og adskillelse af ansvarsområder, hvilket gør det lettere at vedligeholde og udvikle individuelle tjenester. Ændringer i en tjeneste er mindre tilbøjelige til at påvirke andre tjenester.
- Gradvis adoption: Kan implementeres trinvist, hvilket giver dig mulighed for gradvist at migrere fra en monolitisk arkitektur til en microservices-arkitektur. Du kan starte med at sy eksisterende API'er sammen og derefter gradvist nedbryde monolitten i mindre tjenester.
Begrænsninger ved Schema Stitching
Selvom Schema Stitching tilbyder mange fordele, er det vigtigt at være opmærksom på dens begrænsninger:
- Kompleksitet: Implementering og styring af schema stitching kan være komplekst, især i store og komplekse systemer. Omhyggelig planlægning og design er afgørende.
- Performance-overhead: Gatewayen introducerer en vis performance-overhead på grund af det ekstra lag af indirektion og behovet for at delegere forespørgsler og aggregere resultater. Omhyggelig optimering er afgørende for at minimere denne overhead.
- Skemakonflikter: Der kan opstå konflikter, når man fletter skemaer fra forskellige tjenester, især hvis de bruger de samme typenavne eller feltnavne. Dette kræver omhyggeligt skemadesign og potentielt omdøbning af typer og felter.
- Begrænsede avancerede funktioner: Sammenlignet med Apollo Federation mangler Schema Stitching nogle avancerede funktioner som typeudvidelser og nøgledirektiver, hvilket kan gøre det mere udfordrende at håndtere relationer mellem typer på tværs af forskellige skemaer.
- Værktøjsmodenhed: Værktøjerne og økosystemet omkring Schema Stitching er ikke så modne som dem omkring Apollo Federation. Dette kan gøre det mere udfordrende at fejlsøge og løse problemer.
Praktisk implementering af Schema Stitching
Lad os gennemgå et forenklet eksempel på, hvordan man implementerer Schema Stitching ved hjælp af Node.js og graphql-tools
-biblioteket (et populært valg til schema stitching). Dette eksempel involverer to microservices: en brugertjeneste og en produkttjeneste.
1. Definer fjernskemaerne
Først skal du definere GraphQL-skemaerne for hver af fjerntjenesterne.
Brugertjeneste (user-service.js
):
const { buildSchema } = require('graphql');
const userSchema = buildSchema(`
type User {
id: ID!
name: String
email: String
}
type Query {
user(id: ID!): User
}
`);
const users = [
{ id: '1', name: 'Alice Smith', email: 'alice@example.com' },
{ id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];
const userRoot = {
user: (args) => users.find(user => user.id === args.id),
};
module.exports = {
schema: userSchema,
rootValue: userRoot,
};
Produkttjeneste (product-service.js
):
const { buildSchema } = require('graphql');
const productSchema = buildSchema(`
type Product {
id: ID!
name: String
price: Float
userId: ID! # Fremmednøgle til brugertjeneste
}
type Query {
product(id: ID!): Product
}
`);
const products = [
{ id: '101', name: 'Laptop', price: 1200, userId: '1' },
{ id: '102', name: 'Smartphone', price: 800, userId: '2' },
];
const productRoot = {
product: (args) => products.find(product => product.id === args.id),
};
module.exports = {
schema: productSchema,
rootValue: productRoot,
};
2. Opret gateway-tjenesten
Opret nu den gateway-tjeneste, der vil sy de to skemaer sammen.
Gateway-tjeneste (gateway.js
):
const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');
async function createRemoteSchema(uri) {
const fetcher = async (params) => {
const response = await fetch(uri, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});
return response.json();
};
const schema = await introspectSchema(fetcher);
return makeRemoteExecutableSchema({
schema,
fetcher,
});
}
async function main() {
const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
const productSchema = await createRemoteSchema('http://localhost:4002/graphql');
const stitchedSchema = stitchSchemas({
subschemas: [
{ schema: userSchema },
{ schema: productSchema },
],
typeDefs: `
extend type Product {
user: User
}
`,
resolvers: {
Product: {
user: {
selectionSet: `{ userId }`,
resolve(product, args, context, info) {
return info.mergeInfo.delegateToSchema({
schema: userSchema,
operation: 'query',
fieldName: 'user',
args: {
id: product.userId,
},
context,
info,
});
},
},
},
},
});
const app = express();
app.use('/graphql', graphqlHTTP({
schema: stitchedSchema,
graphiql: true,
}));
app.listen(4000, () => console.log('Gateway-server kører på http://localhost:4000/graphql'));
}
main().catch(console.error);
3. Kør tjenesterne
Du skal køre brugertjenesten og produkttjenesten på forskellige porte. For eksempel:
Brugertjeneste (port 4001):
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: rootValue,
graphiql: true,
}));
app.listen(4001, () => console.log('Brugertjeneste kører på http://localhost:4001/graphql'));
Produkttjeneste (port 4002):
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');
const app = express();
app.use('/graphql', graphqlHTTP({
schema: schema,
rootValue: rootValue,
graphiql: true,
}));
app.listen(4002, () => console.log('Produkttjeneste kører på http://localhost:4002/graphql'));
4. Forespørg det sammensyede skema
Nu kan du forespørge det sammensyede skema gennem gatewayen (der kører på port 4000). Du kan køre en forespørgsel som denne:
query {
product(id: "101") {
id
name
price
user {
id
name
email
}
}
}
Denne forespørgsel henter produktet med ID "101" og henter også den tilknyttede bruger fra brugertjenesten, hvilket demonstrerer, hvordan Schema Stitching giver dig mulighed for at forespørge data på tværs af flere tjenester i en enkelt anmodning.
Avancerede Schema Stitching-teknikker
Ud over det grundlæggende eksempel er her nogle avancerede teknikker, der kan bruges til at forbedre din Schema Stitching-implementering:
- Skemadelegering: Dette giver dig mulighed for at delegere dele af en forespørgsel til forskellige tjenester baseret på de data, der anmodes om. For eksempel kan du delegere opløsningen af en `User`-type til brugertjenesten og opløsningen af en `Product`-type til produkttjenesten.
- Skematransformation: Dette indebærer at ændre skemaet for en fjerntjeneste, før det syes ind i det samlede skema. Dette kan være nyttigt til at omdøbe typer og felter, tilføje nye felter eller fjerne eksisterende felter.
- Brugerdefinerede resolvers: Du kan definere brugerdefinerede resolvers i gatewayen til at håndtere komplekse datatransformationer eller til at hente data fra flere tjenester og kombinere dem til et enkelt resultat.
- Kontekstdeling: Det er ofte nødvendigt at dele kontekstinformation mellem gatewayen og fjerntjenesterne, såsom godkendelsestokens eller bruger-ID'er. Dette kan opnås ved at sende kontekstinformation som en del af forespørgselsdelegeringsprocessen.
- Fejlhåndtering: Implementer robust fejlhåndtering for at håndtere fejl, der opstår i fjerntjenesterne, på en elegant måde. Dette kan omfatte logning af fejl, returnering af brugervenlige fejlmeddelelser eller genforsøg på mislykkede anmodninger.
Valget mellem Schema Stitching og Apollo Federation
Selvom Schema Stitching er en levedygtig mulighed for GraphQL Federation, er Apollo Federation blevet det mere populære valg på grund af dens avancerede funktioner og forbedrede udvikleroplevelse. Her er en sammenligning af de to tilgange:
Funktion | Schema Stitching | Apollo Federation |
---|---|---|
Skemadefinition | Bruger eksisterende GraphQL-skemasprog | Bruger et deklarativt skemasprog med direktiver |
Forespørgselsplanlægning | Kræver manuel forespørgselsdelegering | Automatisk forespørgselsplanlægning af Apollo Gateway |
Typeudvidelser | Begrænset understøttelse | Indbygget understøttelse af typeudvidelser |
Nøgledirektiver | Ikke understøttet | Bruger @key -direktivet til at identificere entiteter |
Distribueret sporing | Kræver manuel implementering | Indbygget understøttelse af distribueret sporing |
Værktøjer og økosystem | Mindre modne værktøjer | Mere modne værktøjer og et stort fællesskab |
Kompleksitet | Kan være komplekst at administrere i store systemer | Designet til store og komplekse systemer |
Hvornår skal man vælge Schema Stitching:
- Du har eksisterende GraphQL-tjenester og ønsker hurtigt at kombinere dem.
- Du har brug for en simpel federationsløsning og kræver ikke avancerede funktioner.
- Du har begrænsede ressourcer og vil undgå den overhead, det er at opsætte Apollo Federation.
Hvornår skal man vælge Apollo Federation:
- Du bygger et stort og komplekst system med flere teams og tjenester.
- Du har brug for avancerede funktioner som typeudvidelser, nøgledirektiver og distribueret sporing.
- Du ønsker en mere robust og skalerbar federationsløsning.
- Du foretrækker en mere deklarativ og automatiseret tilgang til federation.
Eksempler og use cases fra den virkelige verden
Her er nogle eksempler fra den virkelige verden på, hvordan GraphQL Federation, herunder Schema Stitching, kan bruges:
- E-handelsplatform: En e-handelsplatform kan bruge GraphQL Federation til at kombinere data fra flere tjenester, såsom en produktkatalogtjeneste, en brugertjeneste, en ordretjeneste og en betalingstjeneste. Dette giver klienter mulighed for nemt at hente alle de oplysninger, de har brug for til at vise produktdetaljer, brugerprofiler, ordrehistorik og betalingsoplysninger.
- Social medieplatform: En social medieplatform kan bruge GraphQL Federation til at kombinere data fra tjenester, der administrerer brugerprofiler, opslag, kommentarer og likes. Dette gør det muligt for klienter effektivt at hente alle de oplysninger, der kræves for at vise en brugers profil, deres opslag samt kommentarer og likes tilknyttet disse opslag.
- Finansiel tjenesteapplikation: En finansiel tjenesteapplikation kan bruge GraphQL Federation til at kombinere data fra tjenester, der administrerer konti, transaktioner og investeringer. Dette giver klienter mulighed for nemt at hente alle de oplysninger, de har brug for til at vise kontosaldi, transaktionshistorik og investeringsporteføljer.
- Content Management System (CMS): Et CMS kan udnytte GraphQL Federation til at integrere data fra forskellige kilder som artikler, billeder, videoer og brugergenereret indhold. Dette muliggør en samlet API til at hente alt indhold relateret til et specifikt emne eller en forfatter.
- Sundhedsapplikation: Integrer patientdata fra forskellige systemer som elektroniske patientjournaler (EPJ), laboratorieresultater og aftalebooking. Dette giver læger et enkelt adgangspunkt til omfattende patientinformation.
Bedste praksis for Schema Stitching
For at sikre en vellykket implementering af Schema Stitching, følg disse bedste praksisser:
- Planlæg dit skema omhyggeligt: Før du begynder at sy skemaer sammen, skal du omhyggeligt planlægge strukturen af det samlede skema. Dette inkluderer at definere relationerne mellem typer på tværs af forskellige skemaer, omdøbe typer og felter for at undgå konflikter og overveje de overordnede dataadgangsmønstre.
- Brug konsistente navngivningskonventioner: Anvend konsistente navngivningskonventioner for typer, felter og operationer på tværs af alle tjenester. Dette vil hjælpe med at undgå konflikter og gøre det lettere at forstå det samlede skema.
- Dokumenter dit skema: Dokumenter det samlede skema grundigt, herunder beskrivelser af typer, felter og operationer. Dette vil gøre det lettere for udviklere at forstå og bruge skemaet.
- Overvåg ydeevne: Overvåg ydeevnen af gatewayen og fjerntjenesterne for at identificere og løse eventuelle performance-flaskehalse. Brug værktøjer som distribueret sporing til at spore anmodninger på tværs af flere tjenester.
- Implementer sikkerhed: Implementer passende sikkerhedsforanstaltninger for at beskytte gatewayen og fjerntjenesterne mod uautoriseret adgang. Dette kan involvere brug af godkendelses- og autorisationsmekanismer samt inputvalidering og output-kodning.
- Versioner dit skema: Når du udvikler dine skemaer, skal du versionere dem passende for at sikre, at klienter kan fortsætte med at bruge ældre versioner af skemaet uden at noget går i stykker. Dette vil hjælpe med at undgå breaking changes og sikre bagudkompatibilitet.
- Automatiser udrulning: Automatiser udrulningen af gatewayen og fjerntjenesterne for at sikre, at ændringer kan udrulles hurtigt og pålideligt. Dette vil hjælpe med at reducere risikoen for fejl og forbedre systemets samlede agilitet.
Konklusion
GraphQL Federation med Schema Stitching tilbyder en kraftfuld tilgang til at bygge samlede API'er fra flere tjenester i en microservices-arkitektur. Ved at forstå dens kernekoncepter, fordele, begrænsninger og implementeringsteknikker kan du udnytte Schema Stitching til at forenkle dataadgang, forbedre skalerbarhed og øge vedligeholdelsesvenligheden. Selvom Apollo Federation er kommet frem som en mere avanceret løsning, forbliver Schema Stitching en levedygtig mulighed for enklere scenarier, eller når eksisterende GraphQL-tjenester skal integreres. Overvej omhyggeligt dine specifikke behov og krav for at vælge den bedste tilgang for din organisation.